package com.mulong.mall.service.support;

import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.ss.usermodel.Cell;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import com.mulong.common.dao.mall.ChannelDao;
import com.mulong.common.domain.pojo.mall.SupplierChannel;
import com.mulong.common.domain.pojo.mall.SupplierChannelSkuDiscount;
import com.mulong.common.domain.pojo.mall.custom.SupplierChannelQuery;
import com.mulong.common.exception.ErrorEnums;
import com.mulong.common.exception.MulongException;
import com.mulong.common.util.MulongUtil;
import com.mulong.mall.domain.bo.manager.UploadSupplierSkuDiscountRecord;
import com.mulong.mall.util.MallRequestContext;

import cn.hutool.poi.excel.ExcelReader;
import lombok.extern.slf4j.Slf4j;

/**
 * ManagerChannelSupport
 * 
 * @author etiger
 * @data 2021-12-04 15:53:03
 */
@Slf4j
@Component
public class ManagerChannelSupport {
    @Autowired
    private ChannelDao channelDao;

    public void addRow(
            HSSFRow row,
            com.mulong.common.domain.pojo.mall.custom.CustomSupplierChannelSkuDiscount record,
            HSSFCellStyle defaultStyle) {
        // 仓库（渠道）名称
        HSSFCell channelCell = row.createCell(0);
        channelCell.setCellStyle(defaultStyle);
        channelCell.setCellValue(record.getChannelTitle());
        // 货号（型号）
        HSSFCell skuCell = row.createCell(1);
        skuCell.setCellStyle(defaultStyle);
        skuCell.setCellValue(record.getSku());
        // 折扣
        HSSFCell discountCell = row.createCell(2);
        discountCell.setCellStyle(defaultStyle);
        discountCell.setCellValue(record.getDiscount() == null ? null : record.getDiscount().toString());
    }

    public List<UploadSupplierSkuDiscountRecord> buildUploadSupplierSkuDiscountRecordList(ExcelReader reader) {
        int rowCount = reader.getRowCount();
        if (rowCount <= 1) {
            log.error("upload file is empty");
            throw new MulongException(ErrorEnums.UPLOAD_FILE_EMPTY);
        }
        List<UploadSupplierSkuDiscountRecord> uploadRecords = new ArrayList<>(rowCount - 1);
        for (int y = 1; y < reader.getRowCount(); ++y) {
            UploadSupplierSkuDiscountRecord uploadRecord = buildUploadSupplierSkuDiscountRecord(reader, y);
            if (uploadRecord != null) {
                uploadRecords.add(uploadRecord);
            }
        }
        List<String> distinctSupplierChannelName = uploadRecords.stream().map(UploadSupplierSkuDiscountRecord::getSupplierChannelValue).distinct().collect(Collectors.toList());
        SupplierChannelQuery supplierChannelQuery = new SupplierChannelQuery();
        supplierChannelQuery.setNameList(distinctSupplierChannelName);
        List<SupplierChannel> supplierChannels = channelDao.query(supplierChannelQuery);
        if (CollectionUtils.isEmpty(supplierChannels)) {
            throw new MulongException(ErrorEnums.HANDLE_FAILED_TEMPLETE.format("所有渠道均未识别"));
        }
        Map<String, SupplierChannel> supplierChannelMap = supplierChannels.stream().collect(Collectors.toMap(SupplierChannel::getName, Function.identity()));
        for (UploadSupplierSkuDiscountRecord item : uploadRecords) {
            String supplierChannelValue = item.getSupplierChannelValue();
            SupplierChannel supplierChannel = supplierChannelMap.get(supplierChannelValue);
            if (supplierChannel == null) {
                throw new MulongException(ErrorEnums.HANDLE_FAILED_TEMPLETE.format("有未识别的渠道[" + supplierChannelValue + "]"));
            }
            item.setSupplierChannel(supplierChannel);
        }
        return uploadRecords;
    }

    private UploadSupplierSkuDiscountRecord buildUploadSupplierSkuDiscountRecord(ExcelReader reader, int rowIndex) {
        Cell supplierChannelCell = reader.getCell(0, rowIndex);
        Cell skuCell = reader.getCell(1, rowIndex);
        Cell discountCell = reader.getCell(2, rowIndex);
        String supplierChannelCellValue = MulongUtil.getStringCellValue(supplierChannelCell);
        if (StringUtils.isBlank(supplierChannelCellValue)) {
            throw new MulongException(ErrorEnums.HANDLE_FAILED_TEMPLETE.format("存在没有填写渠道的记录"));
        }
        String skuCellValue = MulongUtil.getStringCellValue(skuCell);
        if (StringUtils.isBlank(skuCellValue)) {
            throw new MulongException(ErrorEnums.HANDLE_FAILED_TEMPLETE.format("存在没有填写货号的记录"));
        }
        String discountCellValue = MulongUtil.getStringCellValue(discountCell);
        if (StringUtils.isBlank(discountCellValue)) {
            throw new MulongException(ErrorEnums.HANDLE_FAILED_TEMPLETE.format("存在没有填写折扣的记录"));
        }
        UploadSupplierSkuDiscountRecord record = new UploadSupplierSkuDiscountRecord();
        record.setSupplierChannelValue(supplierChannelCellValue);
        record.setSupplierChannel(null);
        record.setSku(skuCellValue);
        record.setDiscount(new BigDecimal(discountCellValue));
        return record;
    }

    public void insertSupplierSkuDiscount(List<UploadSupplierSkuDiscountRecord> records) {
        List<com.mulong.common.domain.pojo.mall.SupplierChannelSkuDiscount> list = records.stream().map(item -> {
            com.mulong.common.domain.pojo.mall.SupplierChannelSkuDiscount e = new com.mulong.common.domain.pojo.mall.SupplierChannelSkuDiscount();
            e.setChannelId(item.getSupplierChannel().getId());
            e.setSku(item.getSku());
            e.setDiscount(item.getDiscount());
            return e;
        }).collect(Collectors.toList());
        checkSupplierSkuDiscountDuplicateBatch(list, 1000);
        try {
            channelDao.addSkuDiscountBatch(list, 1000, MallRequestContext.getUsername());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new MulongException(ErrorEnums.HANDLE_FAILED_TEMPLETE.format(e.getMessage()));
        }
    }

    private void checkSupplierSkuDiscountDuplicateBatch(List<com.mulong.common.domain.pojo.mall.SupplierChannelSkuDiscount> records, int batchSize) {
        List<com.mulong.common.domain.pojo.mall.SupplierChannelSkuDiscount> batchList = new ArrayList<>(batchSize);
        for (com.mulong.common.domain.pojo.mall.SupplierChannelSkuDiscount record : records) {
            batchList.add(record);
            if (batchList.size() >= batchSize) {
                checkSupplierSkuDiscountDuplicate(batchList);
                batchList.clear();
            }
        }
        if (!CollectionUtils.isEmpty(batchList)) {
            checkSupplierSkuDiscountDuplicate(batchList);
        }
    }

    private void checkSupplierSkuDiscountDuplicate(List<com.mulong.common.domain.pojo.mall.SupplierChannelSkuDiscount> records) {
        List<SupplierChannelSkuDiscount> result = channelDao.querySkuDiscountDuplicate(records, 1);
        if (!CollectionUtils.isEmpty(result)) {
            SupplierChannelSkuDiscount duplicateRecord = result.get(0);
            SupplierChannel channel = channelDao.queryById(duplicateRecord.getChannelId());
            String sku = duplicateRecord.getSku();
            String msg = String.format("已有折扣, 渠道[%s] 货号[%s]", channel.getName(), sku);
            throw new MulongException(ErrorEnums.HANDLE_FAILED_TEMPLETE.format(msg));
        }
    }

}
